<template>
  <div style="width: 98px" ref="importBtnRef"><slot>导入</slot></div>
  <a-modal
    v-model:open="open"
    title="导入"
    :footer="null"
    :closable="!loading"
    :maskClosable="!loading"
  >
    <div class="modal-box before-border">
      <div class="file-name">数据库名称:&nbsp;&nbsp;{{ filename }}</div>
      <div class="modal-content">
        <a-progress
          type="circle"
          :percent="percent"
          :size="80"
          :status="error ? 'exception' : null"
        />
        <div
          class="modal-tip"
          v-if="error"
          :title="error?.errorMessage || error?.message"
        >
          文件导入失败
        </div>
        <div class="modal-tip" v-else-if="loading">
          {{ merging ? '保存中...' : '文件导入中...' }}
        </div>
        <div class="modal-tip" v-else>文件导入成功</div>
        <div style="display: flex; justify-content: center">
          <div ref="reuploadBtnRef">
            <a-button v-if="error">重新上传</a-button>
          </div>
          <a-button v-if="loading" @click="onCancel">取消</a-button>
        </div>
      </div>
    </div>
  </a-modal>
</template>
<script setup>
import { ref, computed, onMounted, nextTick, watch } from 'vue'
import {
  useImportFileList,
  useGroupId,
  useDataSourceManager,
} from './provide-context.js'
import { message as Message } from 'ant-design-vue'
import { useAccountStore } from '@/stores/account'
import { storeToRefs } from 'pinia'
import Flow from 'simple-uploader.js'
import SparkMD5 from 'spark-md5'
import { mergeChunks } from '@/api/db.js'
import { useDbType } from './provide-context.js'
import { rewriteURL } from '@/api/db.js'

/**
 * 入参
 */
let props = defineProps({ params: { type: Object, default: () => ({}) } })
/**
 * 事件定义
 */
let emit = defineEmits(['end', 'start'])
/**
 * 全局
 */
// let publishCount = usePublishCount()
let fileList = useImportFileList()
let groupId = useGroupId()
let { update } = useDataSourceManager()
/**
 * 用户信息
 */
let accountStore = useAccountStore()
let account = storeToRefs(accountStore)
/**
 * 交互
 */
let loading = ref(false)
let open = ref(false)
let merging = ref(false)
/**
 * 导入显示
 */
let percent = ref(0)
let filename = ref()
let error = ref()
/**
 * 上传配置
 */

let dbType = useDbType()
let flow = new Flow({
  // testChunks: true,
  target:
    (!APP_MOCK_ENABLE ? import.meta.env.VITE_APP_API_BASE || '' : '') +
    rewriteURL('/data/ed/file/batchImport', dbType),
  // chunkSize: 1024 * 1024,
  // testChunks: true,
  query: { parentId: groupId.value, ...props.params }, //调整成parentId (但是有问题)
  headers: {
    Authorization: 'Bearer ' + account.token.value,
  },
  maxFiles: 1,
  checkChunkUploadedByResponse(chunk, message) {
    // console.log(chunk, message)
    // return true
    try {
      let result = JSON.parse(message)
      // console.log(result)
      if (result.data.skipUpload) {
        return true
      }
      return (result.data.uploaded || []).indexOf(chunk.offset + 1) >= 0
    } catch (e) {}
  },
})

// Handle file add event
flow.on('fileAdded', function (file) {
  // computeMD5(file)
})
flow.on('filesSubmitted', function (file) {
  flow.upload()
})
flow.on('complete', function () {
  flow.cancel()
  // Hide pause/resume when the upload has completed
})
flow.on('fileSuccess', async function (rootFile, file, response, chunk) {
  // console.log('fileSuccess', file, result)
  merging.value = true
  try {
    let result = await mergeChunks(
      {
        identifier: file.chunks[0].file.uniqueIdentifier,
        fileName: rootFile.name,
        totalChunks: chunk.offset + 1,
        ...props.params,
      },
      dbType,
    )
    if (!result.success) {
      return (error.value = result.errorMessage)
    }
  } catch (e) {
    console.log(e)
    error.value = e
  }
  loading.value = false
  merging.value = false

  try {
    //刷新列表
    update()
  } catch (e) {}
  // Reflect that the file upload has completed
})
flow.on('fileError', function () {
  // console.log('fileError', file, result)
  // Reflect that the file upload has resulted in error
  flow.cancel()
  error.value = 'fileError'
  loading.value = false
})
flow.on('fileProgress', function (file) {
  percent.value = parseInt(flow.progress().toFixed(2) * 100)
  // Handle progress for both the file and the overall upload
})
flow.on('uploadStart', function () {
  open.value = true
  loading.value = true
  filename.value = flow.files[0].name
  percent.value = 0
  error.value = null
  // Show pause, hide resume
  emit('start')
})
flow.on('catchAll', function () {
  // console.log.apply(console, arguments)
  // flow.cancel()
})

function onCancel() {
  flow.cancel()
  open.value = false
}
/**
 * 初始化按钮
 */
let importBtnRef = ref()
let reuploadBtnRef = ref()
onMounted(() => {
  nextTick(() => {
    flow.assignBrowse(importBtnRef.value, false, true, { accept: '.colib' })
  })
})
watch(reuploadBtnRef, newReuploadBtnRef => {
  if (newReuploadBtnRef) {
    flow.assignBrowse(newReuploadBtnRef, false, true)
  }
})

/**
 * md5
 */
function computeMD5(file) {
  // let spark = new SparkMD5.ArrayBuffer()
  // console.log(file.uniqueIdentifier)
  // spark.append(file.uniqueIdentifier)
  // // spark.append('file.uniqueIdentifier')
  // file.uniqueIdentifier = spark.end()
  // spark.destroy()

  let fileReader = new FileReader()
  let time = new Date().getTime()
  let blobSlice =
    File.prototype.slice ||
    File.prototype.mozSlice ||
    File.prototype.webkitSlice
  let currentChunk = 0
  const chunkSize = 1024 * 1024
  let chunks = Math.ceil(file.size / chunkSize)
  let spark = new SparkMD5.ArrayBuffer()
  // 文件状态设为"计算MD5"
  file.cmd5 = true //文件状态为“计算md5...”
  file.pause()
  loadNext()
  fileReader.onload = e => {
    // console.log(e.target.result)
    spark.append(e.target.result)
    if (currentChunk < chunks) {
      currentChunk++
      loadNext()
      // 实时展示MD5的计算进度
      // console.log(
      //   `第${currentChunk}分片解析完成, 开始第${
      //     currentChunk + 1
      //   } / ${chunks}分片解析`,
      // )
    } else {
      let md5 = spark.end()
      // console.log(
      //   `MD5计算完毕：${file.name} \nMD5：${md5} \n分片：${chunks} 大小:${
      //     file.size
      //   } 用时：${new Date().getTime() - time} ms`,
      // )
      spark.destroy() //释放缓存
      file.uniqueIdentifier = md5 //将文件md5赋值给文件唯一标识
      file.cmd5 = false //取消计算md5状态
      file.resume() //开始上传
    }
  }
  fileReader.onerror = function () {
    // this.error(`文件${file.name}读取出错，请检查该文件`)
    error.value = 'md5Error'
    file.cancel()
  }
  function loadNext() {
    let start = currentChunk * chunkSize
    let end = start + chunkSize >= file.size ? file.size : start + chunkSize
    fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end))
  }
}
</script>
<style lang="less" scoped>
.file-name {
  // margin-top: 20px;
}
.modal-content {
  text-align: center;
  margin-top: 33px;
  .modal-tip {
    font-size: 22px;
    color: rgba(0, 0, 0, 0.85);
    line-height: 34px;
    font-weight: 500;
    margin: 22px 0;
  }
}
</style>
